// 类
// function first() {
//   console.log(1)
//   return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {
//     console.log(2)
//   }
// }
// function second() {
//   console.log(3)
//   return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {
//     console.log(4)
//   }
// }

// export class Person {
//   name: string = '张三'

//   @first()
//   @second()
//   say() {
//     console.log(`我是${this.name}`)
//   }
// }

// const p1 = new Person();

// 类装饰器
// export function first(constructor: Function) {
//   console.log(constructor)
//   console.log(constructor.prototype)

//   constructor.prototype.yy = () => {

//   }
// }

// @first
// class Son {
//   name = '张三'

//   say() {

//   }
// }

// const s1 = new Son();

// console.log(s1)

// 方法装饰器

// function enumerable(value: boolean) {
//   return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
//     descriptor.value = () => {
//       console.log(123)

//       return '被覆盖了'
//     }
//   };
// }

// export class Greeter {
//   greeting: string;
//   constructor(message: string) {
//     this.greeting = message;
//   }

//   @enumerable(false)
//   greet() {
//     return "Hello, " + this.greeting;
//   }
// }

// const g1 = new Greeter('你好')

// const result = g1.greet()

// console.log(result)

// 属性装饰器

// function format(target: any, propertyKey: string) {
//   console.log(target, propertyKey)
// }

// class Greeter {
//   @format
//   greeting: string;

//   constructor(message: string) {
//     this.greeting = message;
//   }
// }
// const formatMetadataKey = Symbol("format");

// 参数装饰器

// import "reflect-metadata";

// class BugReport {
//   type = "report";
//   title: string;

//   constructor(t: string) {
//     this.title = t;
//   }

//   print(@required verbose: boolean) {
//     if (verbose) {
//       return `type: ${this.type}\ntitle: ${this.title}`;
//     } else {
//      return this.title;
//     }
//   }
// }
// const requiredMetadataKey = Symbol("required");

// function required(target: Object, propertyKey: string | symbol, parameterIndex: number) {
//   console.log(target, propertyKey, parameterIndex)
// }

function change() {
  console.log("装饰器");

  return function (
    target: any,
    propertyKey: string,
    descriptor: PropertyDescriptor
  ) {
    const fn = descriptor.value;

    descriptor.value = function (age: number) {
      if (0 < age && 150 > age) return fn.call(this, age);
    };
  };
}

export class Person {
  name: string;
  age: number;
  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }
  @change()
  changeAge(age: number) {
    this.age = age;
  }
}

const p1 = new Person("张三", 18);

console.log(p1);
p1.changeAge(-5);
console.log(p1);
p1.changeAge(50);
console.log(p1);
